package com.gxar.fusion.authorization.reference;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Maps;
import com.gxar.common.exception.APIRuntimeException;
import com.gxar.fusion.authorization.model.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author linsy
 * @version 1.0
 * @created 2024/1/23 14:52
 */
@Service
@Slf4j
public class AuthReference {

    /**
     * 查询用户菜单
     *
     * @param userId 用户id
     * @param app    app
     * @return 用户菜单
     */
    public List<JSONObject> findMenuByUserId(Long userId, String app) {
        GenericService genericService = this.buildGenericService();
        //封装参数(params为Map<String, Object>，参数名和值)
        Map<String, Object> params = Maps.newLinkedHashMap();
        params.put("app", app);
        params.put("userId", userId);
        params.put("type", 2);
        String[] paramTypes = new String[params.size()];
        Object[] paramValues = new Object[params.size()];
        int i = 0;
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            paramTypes[i] = entry.getValue().getClass().getTypeName();
            paramValues[i] = entry.getValue();
            i++;
        }
        try {
            Object userServiceObject = genericService.$invoke("findMenuByUserId", paramTypes, paramValues);
            if (Objects.nonNull(userServiceObject)) {
                if (userServiceObject instanceof JSONArray) {
                    return JSON.parseArray(userServiceObject.toString(), JSONObject.class);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new APIRuntimeException(ResultCodeEnum.ROLE_MENU_EXCEPTION);
        }
        return null;
    }

    /**
     * 构建范化调用服务
     *
     * @return 范化调用服务
     */
    private GenericService buildGenericService() {
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        // 弱类型接口名
        reference.setApplication(new ApplicationConfig("product-fusion-auth-be"));
        //接口类全限定类名
        reference.setInterface("com.gxar.fusion.auth.api.client.IUserClient");
        reference.setCheck(false);
        //接口版本号
        reference.setVersion("1.0.0");
        // 声明为泛化接口
        reference.setGeneric(true);
        reference.setSerialization("fastjson");
        // 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用
        ReferenceConfigCache cache = ReferenceConfigCache.getCache();
        return cache.get(reference);
    }
}
